﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.SharePoint.Administration;
using System.Collections.ObjectModel;
using Microsoft.SharePoint;

namespace SPALM
{
    internal class RetractAndDeleteSandboxedSolutionsOperation : DeploymentOperation
    {
        private string Solutions;
        private string SiteCollections;

        private string[] solutionNames;
        private string[] solutionFileNames;
        private string[] siteCollectionNames;

        public RetractAndDeleteSandboxedSolutionsOperation(Deployment parentTask, string Solutions, string SiteCollections, int ParsedRetries, int ParsedWaitSecondsAfterFinish, bool ParsedSimulateDeployment)
        : base(parentTask, ParsedRetries, ParsedWaitSecondsAfterFinish, ParsedSimulateDeployment)
        {            
            this.Solutions = Solutions;
            this.SiteCollections = SiteCollections;

            //Parameter extraction
            solutionNames = GetSolutionNames(Solutions);
            solutionFileNames = GetArrayFromString(Solutions);
            siteCollectionNames = GetArrayFromString(SiteCollections);
        }

        public override void CheckPreconditions()
        {
            LogMessage(FormatHeader("Check preconditions"), LogLevel.High);

            //1. Checks
            if (solutionFileNames.Length == 0)
            {
                exceptions.Add("No solutions given in parameter 'Solutions'");
            }

            //1. Checks
            if (siteCollectionNames.Length == 0)
            {
                exceptions.Add("No site collections given in parameter 'Sites'");
            }

            //Existieren die angegebenen Sites
            if (siteCollectionNames.Length > 0)
            {
                LogMessage("Check existing site collections...", LogLevel.Normal);
                foreach (string siteCollectionName in siteCollectionNames)
                {
                    LogMessage("Checking site collection '" + siteCollectionName + "'", LogLevel.Low);
                    if (!SiteCollectionExistsOnServer(siteCollectionName))
                    {
                        exceptions.Add("Site collection '" + siteCollectionName + "' does not exists on server.");
                    }
                }
            }

            //ist eine content DB readonly
            LogMessage("Check if content database is readonly...", LogLevel.Normal);
            foreach (string siteCollectionName in siteCollectionNames)
            {
              using (SPSite site = new SPSite(siteCollectionName))
              {
                if (site != null)
                {
                  if (site.ContentDatabase.IsReadOnly)
                  {
                    exceptions.Add("Content database of site '" + siteCollectionName + "' is read-only.");
                  }
                }
              }
            }

            LogMessage(FormatHeader("Check preconditions finished successfully"), LogLevel.High);
            LogMessage("", LogLevel.High);
        }

        public override void PrepareSystem()
        {
            //LogMessage("Prepare system for Retract Solutions", LogLevel.High);            
        }

        public override void RunOperation()
        {
            LogMessage(FormatHeader("Deactivating and deleting sandboxed solutions"), LogLevel.High);

            //b. Existieren die Lösungen bereits auf dem Server            
            foreach (string siteCollectionName in siteCollectionNames)
            {
              using (SPSite site = new SPSite(siteCollectionName))
              {
                if (site != null)
                {
                  foreach (string solutionName in solutionNames)
                  {
                    LogMessage("Deleting '" + solutionName + "' in site '" + siteCollectionName + "'", LogLevel.Low);
                    if (SolutionExistsInSiteCollection(solutionName, siteCollectionName))
                    {
                      LogMessage("Deactivating '" + solutionName + "' in '" + siteCollectionName + "'...", LogLevel.Normal);
                      try
                      {
                        //finde die solution und deaktiviere                                
                        foreach (SPUserSolution userSolution in site.Solutions)
                        {
                          if (userSolution.Name.Equals(solutionName, StringComparison.InvariantCultureIgnoreCase))
                          {
                            site.Solutions.Remove(userSolution);
                            break;
                          }
                        }

                      }
                      catch (Exception ex)
                      {
                        exceptions.Add("Could not activate sandboxed solution '" + solutionName + "' in site '" + siteCollectionName + "' (" + ex.Message + ")");
                      }

                      //lösche die Solutions
                      LogMessage("Deleting '" + solutionName + "' in '" + siteCollectionName + "'...", LogLevel.Normal);
                      try
                      {
                        SPList catalog = site.RootWeb.GetCatalog(SPListTemplateType.SolutionCatalog);
                        string str = catalog.RootFolder.Url + "/" + solutionName;
                        catalog.RootFolder.Files[str].Delete();
                      }
                      catch (Exception ex)
                      {
                        exceptions.Add("Could not delete sandboxed solution '" + solutionName + "' in site '" + siteCollectionName + "' (" + ex.Message + ")");
                      }
                    }
                    else
                    {
                      LogWarning("Solution '" + solutionName + "' not found in '" + siteCollectionName + "'");
                    }
                  }
                }
                else
                {
                  LogWarning("Sitecollection '" + siteCollectionName + "' does not exists");
                }
              }
            }

            LogMessage(FormatHeader("Deactivating and deleting sandboxed solutions finished"), LogLevel.High);
            LogMessage("", LogLevel.High);
            
        }
                
        public override void ValidateSystem()
        {
            
        }
    }
}
